package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.common.client.AddressAndUserClient;
import com.hmall.common.client.ItemClient;
import com.hmall.common.pojo.Order;
import com.hmall.common.pojo.User;
import com.hmall.common.status.OrderStatus;
import com.hmall.common.pojo.Address;
import com.hmall.common.pojo.Item;
import com.hmall.order.mapper.OrderDetailMapper;
import com.hmall.order.mapper.OrderLogisticsMapper;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.pojo.OrderLogistics;
import com.hmall.order.service.IOrderService;
import com.hmall.order.web.request.OrderRequest;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;

@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private ItemClient itemClient;
    @Autowired
    private AddressAndUserClient addressAndUserClient;
    @Resource
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private OrderLogisticsMapper orderLogisticsMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 创建订单返回订单号
     *
     * @param orderRequest
     * @return
     */
    @Override
    @GlobalTransactional
    public Long createOrder(OrderRequest orderRequest) {
//        生成订单
//        获取订单各项属性
        Item item = itemClient.findById(orderRequest.getItemId());
        if (item == null) {
            throw new RuntimeException("商品不存在");
        }
//        总价
        Long totalFee = orderRequest.getNum() * item.getPrice();
        Address address = addressAndUserClient.findAddressById(orderRequest.getAddressId());
        if (address == null) {
            throw new RuntimeException("地址有误");
        }
        User user = addressAndUserClient.findUserById(address.getUserId());
//        if (orderRequest.getPaymentType() == 3 && user.getBalance() <= totalFee) {
//            throw new RuntimeException("余额不足");
//        }
        Long userId = address.getUserId();
        LocalDateTime now = LocalDateTime.now();

//        组成订单表对象
        Order order = buildOrder(orderRequest, totalFee, userId, now);
//        插入订单表Order
        int insertOrder = orderMapper.insert(order);
        if (insertOrder != 1) {
            throw new RuntimeException("插入Order失败");
        }
//        获取订单id
        Long orderId = order.getId();

//        组成订单详细表对象
        OrderDetail orderDetail = buildOrderDetail(orderRequest, item, now, orderId);
//        插入订单详细表OrderDetail
        int insertorderDetail = orderDetailMapper.insert(orderDetail);
        if (insertorderDetail != 1) {
            throw new RuntimeException("插入OrderDetail失败");
        }

//        组成订单物流对象
        OrderLogistics orderLogistics = buildOrderLogistics(address, now, orderId);

//        插入订单物流表OrderLogistics
        int insertOrderLogistics = orderLogisticsMapper.insert(orderLogistics);
        if (insertOrderLogistics != 1) {
            throw new RuntimeException("插入OrderLogistics失败");
        }

//        减item库存传入商品id和数量
        itemClient.reduceStock(orderRequest.getItemId(), orderRequest.getNum());
//        发送延迟消息
        Message message = MessageBuilder
                .withBody(orderId.toString().getBytes(StandardCharsets.UTF_8))
                .setHeader("x-delay", 10000)
                .build();
//        CorrelationData correlationData = new CorrelationData(orderId.toString());
        rabbitTemplate.convertAndSend("delay.direct", "delay", message);
        log.debug("发送消息成功");
        return orderId;
    }


    //        组成订单物流对象
    private OrderLogistics buildOrderLogistics(Address address, LocalDateTime now, Long orderId) {
        OrderLogistics orderLogistics = new OrderLogistics();
        BeanUtils.copyProperties(address, orderLogistics);
        orderLogistics.setOrderId(orderId);
        return orderLogistics;
    }

    //        组成订单详细表对象
    private OrderDetail buildOrderDetail(OrderRequest orderRequest, Item item, LocalDateTime now, Long orderId) {
        OrderDetail orderDetail = OrderDetail.builder()
                .orderId(orderId)
                .itemId(item.getId())
                .num(orderRequest.getNum())
                .name(item.getName())
                .spec(item.getSpec())
                .price(item.getPrice())
                .image(item.getImage())
                .build();
        return orderDetail;
    }

    //        组成订单表对象
    private Order buildOrder(OrderRequest orderRequest, Long totalFee, Long userId, LocalDateTime now) {
        Order order = Order.builder()
                .totalFee(totalFee)
                .paymentType(orderRequest.getPaymentType())
                .userId(userId)
                .status(OrderStatus.CREATE_ORDER)
                .createTime(now)
                .updateTime(now)
                .build();
        return order;
    }
}
